package spitfire.ksim.node;

import java.text.DateFormat;

import spitfire.ksim.algorithm.FuzzyRuleBase;
import spitfire.ksim.algorithm.RequestAlgoFactory;
import spitfire.ksim.data.TSDRequestData;
import spitfire.ksim.data.TSDResponseData;
import spitfire.ksim.data.TSDUpdateData;
import spitfire.ksim.network.KNetAddress;
import spitfire.ksim.network.KNetwork;
import spitfire.ksim.simulator.KJob;
import spitfire.ksim.simulator.KSimDuration;
import spitfire.ksim.simulator.KSimulator;
import spitfire.ksim.util.TPoint;

/**
 * <p>
 * KGateway is a special node with a {@link FuzzyRuleBase} build in and handles
 * update and request for semantic description from sensor nodes.
 * </p>
 * <ul>
 * <li>When it receives update from sensor node, it will update the
 * {@link FuzzyRuleBase} with the {@link TSDUpdateData} </li>
 * <li>When it receives request from sensor node, it will query the 
 * {@link FuzzyRuleBase} with the {@link TSDRequestData}, and form a 
 * {@link TSDResponseData} if a semantic description is selected.</li>
 * </ul>
 * 
 * <p>
 * Every KGateway instance has an auto assigned unique ID.
 * </p>
 * 
 * @author Adam
 *
 */
public class KGateway extends KNode{

	private static int nextID = 0;
	private final int gwId = nextID++;
	private FuzzyRuleBase fuzzyDb = new FuzzyRuleBase();
	
	public KGateway(KSimulator simulator, KNetwork network, TPoint location) {
		super(simulator, network, location);
		setDisplayName("Gateway-" + gwId + "|" + getNetAddr());
	}

	public static void resetID() {
		nextID = 0;
	}
	
	/**
	 * Set the request algorithm specified by the given algorithm name
	 * 
	 * @param algoName
	 *            - the algorithm name that specifies a combination of request
	 *            algorithm
	 * @see RequestAlgoFactory
	 */
	public void setRequestAlgorithm(String algoName) {
		getFuzzyDb().setRequestAlgorithm(algoName);
	}
	
	/**
	 * @return displayable name of the current request algorithm used on this gateway.
	 */
	public String getRequestAlgorithm() {
		return getFuzzyDb().getRequestAlgorithmName();
	}
	
	@Override
	public void onPacketRecv(KNetAddress srcAddr, Object payload) {
		System.out.println("[" + DateFormat.getDateTimeInstance().format(getSimTime())
				+ "] " + getDisplayName() + " Recv from " + srcAddr + ": " + payload);
		if (payload instanceof TSDRequestData) {
			TSDRequestData request = (TSDRequestData) payload;
			String sd = getFuzzyDb().requestForSD(request.getData());
			if (sd != null) {
				send(srcAddr, new TSDResponseData(sd));
			}
			
		} else if (payload instanceof TSDUpdateData) {
			TSDUpdateData update = (TSDUpdateData) payload;
			getFuzzyDb().updateRuleBase(update.getData(), update.getSd(), update.getNodeId());
		}
	}

	@Override
	public void doJob(KJob job) {
		
	}

	@Override
	public KSimDuration getSimDuration() {
		return null;
	}

	/**
	 * @return ID of the gateway.
	 */
	public int getGwId() {
		return gwId;
	}

	public FuzzyRuleBase getFuzzyDb() {
		return fuzzyDb;
	}

}
